package com.ccteam.fluidmusic.ui.auth

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import cn.hutool.core.lang.Validator
import com.ccteam.fluidmusic.R
import com.ccteam.fluidmusic.databinding.FragmentRegisterBinding
import com.ccteam.fluidmusic.utils.EventObserver
import com.ccteam.fluidmusic.utils.VerifyCodeCountDownTimer
import com.ccteam.fluidmusic.utils.hideKeyboard
import com.ccteam.fluidmusic.view.bean.LoadMessage
import com.ccteam.fluidmusic.widget.SNACKBAR_BOTTOM
import com.ccteam.fluidmusic.widget.snackbar
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch

/**
 * @author Xiaoc
 * @since 2021/3/29
 *
 * 注册界面Fragment
 */
@AndroidEntryPoint
class RegisterFragment : Fragment() {

    private var _binding: FragmentRegisterBinding? = null
    private val binding get() = _binding!!

    /**
     * 用户名是否合法
     */
    private var isNameSuccess: Boolean = false
    /**
     * 密码是否合法
     */
    private var isPasswordSuccess: Boolean = false
    /**
     * 确认密码是否合法
     */
    private var isPasswordConfirmSuccess: Boolean = false
    /**
     * 电话号码是否合法
     */
    private var isPhoneSuccess: Boolean = false
    /**
     * 验证码是否合法
     */
    private var isVerifySuccess: Boolean = false

    private val verifyCountDownTimer = VerifyCodeCountDownTimer()

    companion object{
        // 数字
        val REG_NUMBER = Regex(".*\\d+.*")
        // 小写字母
        val REG_UPPERCASE = Regex(".*[A-Z]+.*")
        // 大写字母
        val REG_LOWERCASE = Regex(".*[a-z]+.*")
        // 特殊符号
        val REG_SYMBOL = Regex(".*[~!@#$%^&*()_+|<>,.?/:;'\\[\\]{}\"]+.*")
    }

    private val registerViewModel by viewModels<RegisterViewModel>()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentRegisterBinding.inflate(inflater,container,false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

        binding.toolbarRegister.setNavigationOnClickListener {
            findNavController().navigateUp()
        }

        viewLifecycleOwner.lifecycleScope.launch {
            verifyCountDownTimer.countDown.collectLatest {
                if(it is VerifyCodeCountDownTimer.Status.Timing){
                    updateTiming(it.currentCountDownNum)
                } else {
                    updateNotTiming()
                }
            }
        }

        /**
         * 观察是否开启获取验证码按钮
         */
        registerViewModel.enableVerifyCodeButton.observe(viewLifecycleOwner, {
            binding.btnVerify.isEnabled = it && verifyCountDownTimer.countDown.value !is VerifyCodeCountDownTimer.Status.Timing
        })

        /**
         * 观察是否开启倒计时
         */
        registerViewModel.enableCountDown.observe(viewLifecycleOwner, EventObserver{
            if(it){
                verifyCountDownTimer.start()
            }
        })

        binding.btnVerify.setOnClickListener {
            if(binding.btnVerify.getLoadingStatus()){
                return@setOnClickListener
            }
            registerViewModel.getVerification(binding.editPhone.editText?.text.toString())
        }

        /**
         * 观察注册加载情况
         * 并在不同情况下加载不同UI
         */
        registerViewModel.loadMessage.observe(viewLifecycleOwner, EventObserver{
            binding.btnRegister.setLoading(it is LoadMessage.Loading)
            when (it) {
                is LoadMessage.Error -> {
                    view.snackbar(it.errorMessage.description.toString(), SNACKBAR_BOTTOM).show()
                }
                is LoadMessage.NotLoading -> {
                    view.snackbar(R.string.description_success_register, SNACKBAR_BOTTOM).show()
                    findNavController().navigateUp()
                }
                else -> {}
            }

        })

        binding.editPhone.addOnEditTextAttachedListener {  inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                if(!Validator.isMobile(text.toString())){
                    isPhoneSuccess = false
                    registerViewModel.setEnableVerify(false)
                    inputLayout.error = getString(R.string.description_error_phone)
                } else {
                    isPhoneSuccess = true
                    registerViewModel.setEnableVerify(true)
                    inputLayout.error = null
                }
            }
        }

        binding.editName.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged {  text, _, _, _ ->
                if(text.toString().isEmpty()){
                    isNameSuccess = false
                    inputLayout.error = getString(R.string.description_error_name_empty)
                } else {
                    isNameSuccess = true
                    inputLayout.error = null
                }
                notifyRegisterButton()
            }
        }

        binding.editPassword.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged {  text, _, _, _ ->
                if(checkPasswordRegex(text.toString())
                    && text.toString().length in 8..16){
                    isPasswordSuccess = true
                    inputLayout.error = null
                } else {
                    isPasswordSuccess = false
                    inputLayout.error = getString(R.string.description_error_name_password)
                }
                notifyRegisterButton()
            }
        }

        binding.editPasswordConfirm.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged {  text, _, _, _ ->
                if(text.toString() != binding.editPassword.editText?.text.toString()){
                    isPasswordConfirmSuccess = false
                    inputLayout.error = getString(R.string.description_error_name_password_confirm)
                } else {
                    isPasswordConfirmSuccess = true
                    inputLayout.error = null
                }
                notifyRegisterButton()
            }
        }

        binding.editVerifyCode.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged {  text, _, _, _ ->
                isVerifySuccess = text.toString().isNotEmpty()
                notifyRegisterButton()
            }
        }

        binding.btnRegister.setProgressButtonOnClickListener {
            hideKeyboard()
            registerViewModel.register(
                binding.editPhone.editText?.text.toString(),
                binding.editName.editText?.text.toString(),
                binding.editPassword.editText?.text.toString(),
                binding.editVerifyCode.editText?.text.toString()
            )
        }
    }

    /**
     * 判断密码是否符合条件
     * 必须满足 数字，字母，特殊字符两种类型及以上才满足
     * @return true 通过条件 false 不通过
     */
    private fun checkPasswordRegex(password: String): Boolean{
        var i = 0
        if(password.matches(REG_NUMBER)){
            i++
        }
        if(password.matches(REG_UPPERCASE)){
            i++
        }
        if(password.matches(REG_UPPERCASE) || password.matches(REG_LOWERCASE)){
            i++
        }
        if(password.matches(REG_SYMBOL)){
            i++
        }
        return i >= 2
    }

    private fun notifyRegisterButton() = with(binding){
        btnRegister.isEnabled = isNameSuccess
                && isPhoneSuccess && isPasswordConfirmSuccess
                && isPasswordSuccess && isVerifySuccess
    }

    private fun updateTiming(countDownNum: Int){
        binding.btnVerify.isEnabled = false
        binding.btnVerify.text = countDownNum.toString()
    }

    private fun updateNotTiming(){
        binding.btnVerify.isEnabled = true && registerViewModel.enableVerifyCodeButton.value == true
        binding.btnVerify.text = getString(R.string.description_get_verification)
    }

    override fun onDestroyView() {
        super.onDestroyView()
        binding.editPhone.clearOnEditTextAttachedListeners()
        binding.editName.clearOnEditTextAttachedListeners()
        binding.editPassword.clearOnEditTextAttachedListeners()
        binding.editPasswordConfirm.clearOnEditTextAttachedListeners()

        verifyCountDownTimer.cancel()

        _binding = null
    }
}